package com.tencreat.service.pay.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.lock.annotation.Lock4j;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConfig;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.tencreat.common.constant.Lock4jConstant;
import com.tencreat.common.constant.MallConstants;
import com.tencreat.common.core.domain.entity.SysDictData;
import com.tencreat.common.core.domain.entity.SysUser;
import com.tencreat.common.core.domain.model.LoginUser;
import com.tencreat.common.enums.*;
import com.tencreat.common.enums.mall.AllEnum;
import com.tencreat.common.event.PaySuccessEvent;
import com.tencreat.common.utils.*;
import com.tencreat.domain.account.MallStore;
import com.tencreat.domain.account.MallUser;
import com.tencreat.domain.mall.*;
import com.tencreat.domain.mall.dto.OrderMallSubmitDTO;
import com.tencreat.mapper.pt.MallPtUsersMapper;
import com.tencreat.service.account.IMallStoreService;
import com.tencreat.service.account.IMallUserService;
import com.tencreat.service.mall.*;
import com.tencreat.service.pay.TradeService;
import com.tencreat.service.pt.IMallPtSignCouponRecordService;
import com.tencreat.service.system.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Stream;

@Slf4j
@Service
public class TradeServiceImpl implements TradeService {
    private final static Logger logger = LoggerFactory.getLogger("sys_pay");

    @Autowired
    private IMallOrderService iMallOrderService;

    @Autowired
    private IMallMessageInformService mallMessageInformService;

    @Autowired
    private IMallUserService mallUserService;

    @Autowired
    private IMallOrderGoodsService mallOrderGoodsService;

    @Autowired
    private IMallGoodsService mallGoodsService;

    @Autowired
    IMallGoodsKillService mallGoodsKillService;

    @Autowired
    IMallPtSignCouponRecordService ptSignCouponRecordService;

    @Autowired
    IMallGoodsCutOrderService mallGoodsCutOrderService;

    @Autowired
    IMallGoodsHelpCutUserService helpCutUserService;

    //@Autowired
    //IMallGoodsCutService goodsCutService;

    @Autowired
    MallPtUsersMapper ptUsersMapper;

    @Autowired
    IMallGoodsCollageService mallGoodsCollageService;
    @Autowired
    IMallGoodsCollageOrderService mallGoodsCollageOrderService;

    @Autowired
    private IMallGoodsNormsService mallGoodsNormsService;

    @Resource
    private RabbitSendUtils rabbitUtils;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private IMallStoreService mallStoreService;

    @Override
    public JSONObject generateTrade(OrderMallSubmitDTO orderParam, LoginUser loginUser, PaySuccess paySuccess) {
        return null;
    }

    @Lock4j(name = Lock4jConstant.CANCEL_ORDER, keys = "#order.orderSn", acquireTimeout = 30000)
    @Override
    public void afterPaySuccess(String payId, MallOrder order) {
        // 订单状态校验
        logger.info(String.format("进入支付成功业务回调,订单id：%s", order.getId()));
        int count = iMallOrderService.lambdaQuery().eq(MallOrder::getId, order.getId()).eq(MallOrder::getStatusUser, UserOrderStatus.CANCEL_PAY).count();
        if (count != 0) {
            log.info("订单支付成功回调时，已被取消支付：{}", order);
            iMallOrderService.lambdaUpdate().set(MallOrder::getOrderErrorStatus, OrderErrorStatusEnum.CANCEL).eq(MallOrder::getId, order.getId()).update();
            return;
        }

        // 订单信息设置
        order.setPayId(payId);
        order.setStatusUser(UserOrderStatus.OK);

        if (order.getOrderType().equals(OrderType.SHOP)) {
            order.setStatusShop(ShopOrderStatus.WAIT_DELIVER);
            order.setOrderStatus(OrderStatus.WAIT_DELIVER);
        }
        if (order.getOrderType().equals(OrderType.STORE)) {
            order.setStatusShop(ShopOrderStatus.WAIT_USE);
            order.setOrderStatus(OrderStatus.WAIT_USE);
        }
        if (OrderType.QR_CODE_ORDER.equals(order.getOrderType())) {
            order.setStatusShop(ShopOrderStatus.DAI_CENTXT);
            order.setOrderStatus(OrderStatus.DAI_CENTXT);
        }

        order.setUpdateTime(LocalDateTime.now());

        // 订单支付成功通知 （监听通知处理需实现 implements ApplicationListener<PaySuccessEvent>）
        applicationContext.publishEvent(new PaySuccessEvent(order));

        // 订单状态修改
        orderGoods(order);
        iMallOrderService.updateById(order);
    }

    //同步修改orderGoods订单状态
    private void orderGoods(MallOrder order) {
        MallOrderGoods orderGoods = new MallOrderGoods();
        orderGoods.setOrderSn(order.getOrderSn());
        List<MallOrderGoods> mallOrderGoods = mallOrderGoodsService.selectMallOrderGoodsList(orderGoods);
        MallOrder mallOrder = iMallOrderService.lambdaQuery().eq(MallOrder::getOrderSn, order.getOrderSn()).one();
        MallStore mallStore = mallStoreService.lambdaQuery().eq(MallStore::getId, mallOrder.getStoreId()).one();


        for (MallOrderGoods mallOrderGood : mallOrderGoods) {
            MallGoods goods = mallGoodsService.getById(mallOrderGood.getGoodsId());
            MallGoodsNorms goodsNorms = mallGoodsNormsService.getById(mallOrderGood.getNormsId());
            if ("店铺扫码支付".equals(mallOrderGood.getGoodsName())) {
                //获取订单支付价格
                mallOrderGood.setOrderStatus(order.getOrderStatus());
                mallOrderGood.setAftersaleStatus(0);
                BigDecimal supplyPrice = mallOrderGood.getPayPrice().divide(new BigDecimal("2.00"),2, RoundingMode.DOWN);
                rabbitUtils.sendBalanceMessage(mallStore.getUuid(), supplyPrice, AllEnum.BalanceChangeTypeEnums.INCOME.getType(),
                        BalanceBusinessType.SCAN, "店铺扫码订单", mallOrderGood.getOrderGoodsSn(), BalanceTypeEnum.STORE_FINANCE);
            } else {
                if (goods == null) {
                    continue;
                }
                mallOrderGood.setOrderStatus(order.getOrderStatus());
                mallOrderGood.setAftersaleStatus(0);
                // 根据上传的后台用户ID 查询 前端用户ID
                SysUser sysUser = sysUserService.selectUserById(goods.getUserId());
                MallUser mallUser = mallUserService.lambdaQuery().eq(MallUser::getMobile, sysUser.getPhonenumber()).one();
                // 如果是供应商的商品,给供应商增加流水，以及增加供应商收益
                if (goods.getSupplier() == 1 && mallUser != null) {
                    // 供应价格
                    BigDecimal supplyPrice = goodsNorms.getSupplyPrice().multiply(new BigDecimal(mallOrderGood.getNumber()));
                    rabbitUtils.sendBalanceMessage(mallUser.getUuid(), supplyPrice, AllEnum.BalanceChangeTypeEnums.INCOME.getType(),
                            BalanceBusinessType.ORDER_ADD, "订单收入", mallOrderGood.getOrderGoodsSn(), BalanceTypeEnum.FINANCE_WAIT);

                }
                //如果是店铺核销订单,则给店铺增加待结算货款
                if (goods.getStore() == 1 && mallUser != null) {
                    //如果是店铺扫码订单,则给店铺增加货款
                    mallOrder = iMallOrderService.lambdaQuery().eq(MallOrder::getOrderSn, order.getOrderSn()).one();
                    mallStore = mallStoreService.lambdaQuery().eq(MallStore::getId, mallOrder.getStoreId()).one();
                    // 供应价格
                    BigDecimal supplyPrice = goods.getSupplyPrice().multiply(new BigDecimal(mallOrderGood.getNumber()));
                    rabbitUtils.sendBalanceMessage(mallUser.getUuid(), supplyPrice, AllEnum.BalanceChangeTypeEnums.INCOME.getType(),
                            BalanceBusinessType.STORE_SALE, "销售", mallOrderGood.getOrderGoodsSn(), BalanceTypeEnum.STORE_FINANCE_WAIT);
                }

            }
        }
        mallOrderGoodsService.updateBatchById(mallOrderGoods);
    }

    private void income(MallOrderGoods order, MallGoods goods) {
        //购买商品的用户
        MallUser mallUser = mallUserService.lambdaQuery().select(MallUser::getId, MallUser::getReferrerUuid).eq(MallUser::getUuid, order.getUuid()).one();

        //找到对应订单
        MallOrder mallOrder = iMallOrderService.lambdaQuery().eq(MallOrder::getOrderSn, order.getOrderSn()).one();

        //找到商品所对应的商家
        MallStore mallStore = mallStoreService.lambdaQuery().eq(MallStore::getId, mallOrder.getStoreId()).one();

        //商家用户
        MallUser one = mallUserService.lambdaQuery().eq(MallUser::getUuid, mallStore.getUuid()).one();


        if (Stream.of(OrderType.QR_CODE_ORDER).anyMatch(orderType -> orderType.compareTo(order.getOrderType()) == 0)) {
            List<SysDictData> wxPayConfig = DictUtils.getDictCache("dividend");
            if (wxPayConfig != null) {
                MallUser parent = mallUserService.lambdaQuery().eq(MallUser::getUuid, one.getReferrerUuid()).one();
                if (parent != null) {
                    wxPayConfig.forEach(x -> {
                        BigDecimal amount = order.getPayPrice();
                        BigDecimal actualPush = amount.multiply(new BigDecimal(x.getDictValue()).divide(BigDecimal.valueOf(100), 6, BigDecimal.ROUND_DOWN)).setScale(2, BigDecimal.ROUND_DOWN);
                        if ("storeReferrer".equals(x.getDictLabel())) {
                            rabbitUtils.sendBalanceMessage(parent.getUuid(), actualPush, AllEnum.BalanceChangeTypeEnums.INCOME.getType(), BalanceBusinessType.STORE_REFERRER, "推荐商家奖励-直推", order.getOrderGoodsSn(), BalanceTypeEnum.CONSUMER_ROLL);
                        }
                        if ("inStoreReferrer".equals(x.getDictLabel())) {
                            rabbitUtils.sendBalanceMessage(parent.getReferrerUuid(), actualPush, AllEnum.BalanceChangeTypeEnums.INCOME.getType(), BalanceBusinessType.IN_STORE_REFERRER, "推荐商家奖励-间推", order.getOrderGoodsSn(), BalanceTypeEnum.CONSUMER_ROLL);
                        }
                    });
                }
            }
        }
    }

    public void orderGoodsIncome(MallOrderGoods orderGoods) {
        List<MallOrderGoods> mallOrderGoods = mallOrderGoodsService.selectMallOrderGoodsList(orderGoods);
        for (MallOrderGoods mallOrderGood : mallOrderGoods) {
//            MallGoods goods = mallGoodsService.getById(mallOrderGood.getGoodsId());
//            // 商品参与分佣 增加待结算收益
//            if (goods.getIsBonus() == 1) {
//                income(mallOrderGood, goods);
//            }

            if ("店铺扫码支付".equals(mallOrderGood.getGoodsName())){
                income(mallOrderGood, null);
            }
        }
    }
}
